﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using GMME.Model.Rtm;
using GMME.Model.Rtm.Req;
using GMME.Model.Rtm.Result;
using UnityEngine;

namespace GMME
{
    /// <summary>
    /// 在 editor 中 mock sdk的行为或者检查参数是否正确，方便在editor调试和验证。
    /// </summary>
    public class GameMediaEngineForEditor : GameMediaEngine
    {
        /// <summary>
        /// 如果需要模拟回调，需要在触发回调的方法中使用_eventHandler.xx调用。
        /// </summary>
        private IGameMMEEventHandler _eventHandler;

        private const int Code = 0;

        private const string Msg = "editor mock callback";

        private static readonly GameMediaEngineForEditor Instance = new();


        private GameMediaEngineForEditor()
        {
        }

        public static GameMediaEngineForEditor GetInstance()
        {
            return Instance;
        }

        public GameMediaEngine CreateEngine(EngineCreateParams engineParams, IGameMMEEventHandler callBackHandler)
        {
            Debug.Log("call CreateEngine in sdk mocker, and will be callback onCreate after moment");
            _eventHandler = callBackHandler;
            Task.Run(() => _eventHandler.onCreate(Code, Msg));
            return Instance;
        }

        public void DestroyEngine()
        {
            Debug.Log("call DestroyEngine in sdk mocker, and will be callback onDestroy after moment");
            Task.Run(() => _eventHandler.onDestroy(Code, Msg));
        }


        public override void JoinTeamRoom(string roomId)
        {
            Debug.Log("call JoinTeamRoom in sdk mocker, and will be callback onJoinTeamRoom after moment");
            Task.Run(() => _eventHandler.onJoinTeamRoom(roomId, Code, Msg));
        }

        public override void JoinNationalRoom(string roomId, int roleType)
        {
            Debug.Log("call JoinNationalRoom in sdk mocker, and will be callback onJoinNationalRoom after moment");
            Task.Run(() => _eventHandler.onJoinNationalRoom(roomId, Code, Msg));
        }

        public override void JoinRangeRoom(string roomId)
        {
            Debug.Log("call EnableMic in sdk mocker, and no callback");
        }

        public override void SwitchRoom(string roomId)
        {
            Debug.Log("call SwitchRoom in sdk mocker, and will be callback onSwitchRoom after moment");
            Task.Run(() => _eventHandler.onSwitchRoom(roomId, Code, Msg));
        }

        public override void LeaveRoom(string roomId, string ownerId)
        {
            Debug.Log("call LeaveRoom in sdk mocker, and will be callback onLeaveRoom after moment");
            Task.Run(() => _eventHandler.onLeaveRoom(roomId, Code, Msg));
        }

        public override void TransferOwner(string roomId, string ownerId)
        {
            Debug.Log("call TransferOwner in sdk mocker, and will be callback onTransferOwner after moment");
            Task.Run(() => _eventHandler.onTransferOwner(roomId, Code, Msg));
        }

        public override int EnableMic(bool isEnabled)
        {
            Debug.Log("call EnableMic in sdk mocker, and no callback");
            return 0;
        }

        public override void MutePlayer(string roomId, string openId, bool isMuted)
        {
            Debug.Log("call MutePlayer in sdk mocker, and will be callback onMutePlayer after moment");
            Task.Run(() => _eventHandler.onMutePlayer(roomId, openId, isMuted, Code, Msg));
        }

        public override void MuteAllPlayers(string roomId, bool isMuted)
        {
            Debug.Log("call MuteAllPlayers in sdk mocker, and will be callback onMuteAllPlayers after moment");
            List<string> openIdList = new();
            Task.Run(() => _eventHandler.onMuteAllPlayers(roomId, openIdList, true, Code, Msg));
        }

        public override Room GetRoom(string roomId)
        {
            Debug.Log("call GetRoom in sdk mocker, and no callback");
            // 自定义房间信息，方便调试。
            Room room = new();
            room.Players = new List<Player>();
            room.OwnerId = "123";
            return room;
        }

        public override void EnableSpeakersDetection(string roomId, int interval)
        {
            Debug.Log(
                "call EnableSpeakersDetection sdk mocker, and will be callback onSpeakersDetectionEx after moment");
            List<string> openIdList = new();
            List<VolumeInfo> volumeInfoList = new();
            Task.Run(() => _eventHandler.onSpeakersDetectionEx(volumeInfoList, openIdList));
        }

        public override void ForbidAllPlayers(string roomId, bool isForbidden)
        {
            Debug.Log("call ForbidAllPlayers in sdk mocker, and will be callbadk onForbidAllPlayers after moment");
            List<string> openIdList = new();
            Task.Run(() => _eventHandler.onForbidAllPlayers(roomId, openIdList, isForbidden, Code, Msg));
        }


        public override void ForbidPlayer(string roomId, string openId, bool isForbidden)
        {
            Debug.Log("call ForbidPlayer in sdk mocker, and will be callback onForbidPlayer after moment");
            Task.Run(() => _eventHandler.onForbidPlayer(roomId, openId, isForbidden, Code, Msg));
        }

        public override int EnableVoiceConversion(string roomId, int voiceType)
        {
            Debug.Log("call EnableVoiceConversion in sdk mocker, and no callback");
            return 0;
        }

        public override int GetVoiceConversionType(string roomId)
        {
            Debug.Log("call GetVoiceConversionType in sdk mocker, and no callback");
            return 0;
        }

        public override int EnableEarsBack(bool enable)
        {
            Debug.Log("call EnableEarsBack in sdk mocker, and no callback");
            return 0;
        }

        public override bool IsEarsBackEnable()
        {
            Debug.Log("call IsEarsBackEnable in sdk mocker, and no callback");
            return true;
        }

        public override void StartRecordAudioToText(VoiceParam voiceParam)
        {
            Debug.Log("call StartRecordAudioToText in sdk mocker, and no callback");
        }

        public override void StopRecordAudioToText()
        {
            Debug.Log("call StopRecordAudioToText in sdk mocker, and no callback");
        }

        public override void StartRecordAudioMsg(string filePath)
        {
            Debug.Log("call StartRecordAudioMsg in sdk mocker, and no callback");
        }

        public override void StartRecordAudioMsg(string filePath, int voiceType)
        {
            Debug.Log("call StartRecordAudioMsgWithVoiceType in sdk mocker, and no callback");
        }

        public override void StopRecordAudioMsg()
        {
            Debug.Log("call StopRecordAudioMsg in sdk mocker, and will be callback onRecordAudioMsg after moment");
            Task.Run(() => _eventHandler.onRecordAudioMsg("filePath", Code, Msg));
        }

        public override void UploadAudioMsgFile(string filePath, int msTimeOut)
        {
            Debug.Log("call UploadAudioMsgFile in sdk mocker, and will be callback onUploadAudioMsgFile after moment");
            Task.Run(() => _eventHandler.onUploadAudioMsgFile(filePath, "fileId", Code, Msg));
        }

        public override void DownloadAudioMsgFile(string fileId, string filePath, int msTimeOut)
        {
            Debug.Log(
                "call DownloadAudioMsgFile in sdk mocker, and will be callback onDownloadAudioMsgFile after moment");
            Task.Run(() => _eventHandler.onDownloadAudioMsgFile(filePath, fileId, Code, Msg));
        }

        public override AudioMsgFileInfo GetAudioMsgFileInfo(string filePath)
        {
            Debug.Log("call GetAudioMsgFileInfo in sdk mocker, and no callback");
            return new();
        }

        public override void PlayAudioMsg(string filePath)
        {
            Debug.Log("call PlayAudioMsg in sdk mocker, and will be callback onPlayAudioMsg after moment");
            Task.Run(() => _eventHandler.onPlayAudioMsg(filePath, Code, Msg));
        }

        public override void StopPlayAudioMsg()
        {
            Debug.Log("call StopPlayAudioMsg in sdk mocker, and no callback");
        }

        public override void StartDetectAudioFile(string fileId)
        {
            Debug.Log("call StartDetectAudioFile in sdk mocker, and no callback");
            Task.Run(() => _eventHandler.onStartDetectAudioFile(fileId, Code, Msg));
        }

        public override int PlayLocalAudioClip(LocalAudioInfo localAudioInfo)
        {
            Debug.Log(
                "call PlayLocalAudioClip in sdk mocker, and will be callback onAudioClipStateChangedNotify after moment");
            AudioPlayStateInfo audioPlayStateInfo = new();
            Task.Run(() => _eventHandler.onAudioClipStateChangedNotify(audioPlayStateInfo));
            return 0;
        }

        public override int StopLocalAudioClip(int soundId)
        {
            Debug.Log("call StopLocalAudioClip in sdk mocker, and no callback");
            return 0;
        }

        public override int StopAllLocalAudioClips()
        {
            Debug.Log("call StopAllLocalAudioClips in sdk mocker, and no callback");
            return 0;
        }

        public override int PauseLocalAudioClip(int soundId)
        {
            Debug.Log("call PauseLocalAudioClip in sdk mocker, and no callback");
            return 0;
        }

        public override int PauseAllLocalAudioClips()
        {
            Debug.Log("call PauseAllLocalAudioClips in sdk mocker, and no callback");
            return 0;
        }

        public override int ResumeLocalAudioClip(int soundId)
        {
            Debug.Log("call ResumeLocalAudioClip in sdk mocker, and no callback");
            return 0;
        }

        public override int ResumeAllLocalAudioClips()
        {
            Debug.Log("call ResumeAllLocalAudioClips in sdk mocker, and no callback");
            return 0;
        }

        public override int GetVolumeOfLocalAudioClip(int soundId)
        {
            Debug.Log("call GetVolumeOfLocalAudioClip in sdk mocker, and no callback");
            return 0;
        }

        public override int GetLocalAudioClipsVolume()
        {
            Debug.Log("call GetLocalAudioClipsVolume in sdk mocker, and no callback");
            return 0;
        }

        public override int SetVolumeOfLocalAudioClip(int soundId, int volume)
        {
            Debug.Log("call SetVolumeOfLocalAudioClip in sdk mocker, and no callback");
            return 0;
        }

        public override int SetLocalAudioClipsVolume(int volume)
        {
            Debug.Log("call SetLocalAudioClipsVolume in sdk mocker, and no callback");
            return 0;
        }

        public override int SetAudioRecvRange(int range)
        {
            Debug.Log("call SetAudioRecvRange in sdk mocker, and no callback");
            return 0;
        }

        public override int UpdateSelfPosition(SelfPosition selfPosition)
        {
            Debug.Log("call UpdateSelfPosition in sdk mocker, and no callback");
            return 0;
        }

        public override int UpdateRemotePosition(RemotePlayerPosition[] positions)
        {
            Debug.Log("call UpdateRemotePosition in sdk mocker, and no callback");
            return 0;
        }

        public override void ClearAllRemotePositions()
        {
            Debug.Log("call ClearAllRemotePositions in sdk mocker, and no callback");
        }

        public override void ClearRemotePlayerPosition(string openId)
        {
            Debug.Log("call ClearRemotePlayerPosition in sdk mocker, and no callback");
        }

        public override int InitSpatialSound()
        {
            Debug.Log("call InitSpatialSound in sdk mocker, and no callback");
            return 0;
        }

        public override int EnableSpatialSound(string roomId, bool enable)
        {
            Debug.Log("call EnableSpatialSound in sdk mocker, and no callback");
            return 0;
        }

        public override bool IsEnableSpatialSound(string roomId)
        {
            Debug.Log("call IsEnableSpatialSound in sdk mocker, and no callback");
            return true;
        }

        #region rtm

        /**
         * 订阅RTM频道
         *
         * @param req 订阅RTM频道请求对象
         */
        public override void SubscribeRtmChannel(SubscribeRtmChannelReq req)
        {
        }

        /**
         * 取消订阅RTM频道
         *
         * @param req 取消订阅RTM频道请求对象
         */
        public override void UnSubscribeRtmChannel(UnSubscribeRtmChannelReq req)
        {
        }

        /**
         * 查询已订阅RTM频道信息
         *
         * @return 已订阅频道结果
         */
        public override GetRtmSubscribedChannelInfoResult GetRtmSubscribedChannelInfo()
        {
            return new GetRtmSubscribedChannelInfoResult();
        }

        /**
         * 查询RTM频道信息
         *
         * @param req 查询RTM频道信息请求对象
         */
        public override void GetRtmChannelInfo(GetRtmChannelInfoReq req)
        {
        }

        /**
         * 发布RTM频道信息
         *
         * @param req 发布RTM频道信息请求对象
         * @return 客户端本地生成的 clientMsgId
         */
        public override String PublishRtmChannelMessage(PublishRtmChannelMessageReq req)
        {
            return null;
        }

        /**
         * 发布RTM点对点信息
         *
         * @param req 发布RTM点对点信息请求对象
         * @return 客户端本地生成的 clientMsgId
         */
        public override String PublishRtmPeerMessage(PublishRtmPeerMessageReq req)
        {
            return null;
        }

        /**
         * 设置RTM频道内玩家属性
         *
         * @param req 设置RTM频道内玩家属性请求对象
         */
        public override void SetRtmChannelPlayerProperties(SetRtmChannelPlayerPropertiesReq req)
        {
        }

        /**
         * 查询RTM频道内玩家属性
         *
         * @param req 查询RTM频道内玩家属性请求对象
         */
        public override void GetRtmChannelPlayerProperties(GetRtmChannelPlayerPropertiesReq req)
        {
        }

        /**
         * 删除RTM频道内玩家属性
         *
         * @param req 删除RTM频道内玩家属性请求对象
         */
        public override void DeleteRtmChannelPlayerProperties(DeleteRtmChannelPlayerPropertiesReq req)
        {
        }

        /**
         * 设置RTM频道属性
         *
         * @param req 设置RTM频道属性请求对象
         */
        public override void SetRtmChannelProperties(SetRtmChannelPropertiesReq req)
        {
        }

        /**
         * 查询RTM频道属性
         *
         * @param req 查询RTM频道属性请求对象
         */
        public override void GetRtmChannelProperties(GetRtmChannelPropertiesReq req)
        {
        }

        /**
         * 删除RTM频道属性
         *
         * @param req 删除RTM频道属性请求对象
         */
        public override void DeleteRtmChannelProperties(DeleteRtmChannelPropertiesReq req)
        {
        }

        /**
         * 查询RTM频道历史消息
         *
         * @param req 查询RTM频道历史消息请求对象
         */
        public override void GetRtmChannelHistoryMessages(GetRtmChannelHistoryMessagesReq req)
        {
        }

        #endregion
    }
}
#endif